/*
 * 文件名：UserCtlCmdServiceImpl.java
 * 版权：亚信联创版权所有
 * 描述：TODO
 * 修改人：yuanze
 * 修改时间：2014年10月31日
 * 修改内容：TODO
 */
package com.ailk.bigdata.etl.realstream.server.protocal.aipr.service.impl;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ailk.bigdata.etl.realstream.server.dao.RealStreamUnitDao;
import com.ailk.bigdata.etl.realstream.server.dao.RealsocksUserDao;
import com.ailk.bigdata.etl.realstream.server.dao.impl.RealStreamUnitDaoPGImpl;
import com.ailk.bigdata.etl.realstream.server.dao.impl.RealsocksUserDaoImpl;
import com.ailk.bigdata.etl.realstream.server.model.CmdEnum;
import com.ailk.bigdata.etl.realstream.server.model.RealStreamUnit;
import com.ailk.bigdata.etl.realstream.server.model.RealStreamUser;
import com.ailk.bigdata.etl.realstream.server.model.RealsocksUser;
import com.ailk.bigdata.etl.realstream.server.model.ResponseCodeEnum;
import com.ailk.bigdata.etl.realstream.server.protocal.aipr.service.UserCtlCmdService;
import com.ailk.bigdata.etl.realstream.server.tools.RealStreamTool;

/**
 * @description 实时流命令端口处理
 * @author [yuanze]
 * @version [版本号,2014年10月31日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class UserCtlCmdServiceImpl implements UserCtlCmdService
{

	private static final Logger logger = LoggerFactory.getLogger(UserCtlCmdServiceImpl.class);

	private static CTLSocketListenThread ctlSocketListenT;

	/**
	 * 
	 * @see com.ailk.bigdata.etl.realstream.server.service.UserCtlCmdService#initUserCtlCmdListen()
	 */
	public void initUserCtlCmdListen()
	{
		if (ctlSocketListenT == null)
		{
			ctlSocketListenT = new CTLSocketListenThread();
		}
		if (!ctlSocketListenT.isAlive())
		{
			ctlSocketListenT.start();
		}
	}

	/**
	 * @see com.ailk.bigdata.etl.realstream.server.service.UserCtlCmdService#registerUser(java.lang.String,
	 *      com.ailk.bigdata.etl.realstream.server.model.RealStreamUser)
	 */
	public String registerUser(String cmd, RealStreamUser user)
	{
		// 判断用户是否注册过用户名
		if (StringUtils.isEmpty(user.getUserName()))
		{
			Pattern p = Pattern.compile(CmdEnum.USER.getPattern());
			Matcher m = p.matcher(cmd);
			// 校验用户是否存在
			if (m.find())
			{
				String userName = m.group(1);
				RealsocksUserDao realsocksUserDao = new RealsocksUserDaoImpl();
				RealsocksUser realsocksUser = realsocksUserDao.findByUserName(userName);
				if (realsocksUser != null)
				{
					user.setUserName(userName);
					logger.info("用户名[" + userName + "]需要密码......");
					return String.valueOf(ResponseCodeEnum.CMDEXECUTESUC.getCode());
				}
				else
				{
					logger.info("用户名[" + userName + "]不存在.......");
					return String.valueOf(ResponseCodeEnum.INVALIDCMDPARAM.getCode());
				}
			}
		}
		logger.info("用户[" + user.getUserName() + "]已经默认为该连接用户 不能改变......");
		return String.valueOf(ResponseCodeEnum.ERRORCMDSEQ.getCode());
	}

	/**
	 * @see com.ailk.bigdata.etl.realstream.server.service.UserCtlCmdService#verifyUserPwd(java.lang.String,
	 *      com.ailk.bigdata.etl.realstream.server.model.RealStreamUser)
	 */
	public String verifyUserPwd(String cmd, RealStreamUser user)
	{
		if (StringUtils.isNotEmpty(user.getUserName()) && StringUtils.isEmpty(user.getUserPwd()))
		{
			Pattern p = Pattern.compile(CmdEnum.PASS.getPattern());
			Matcher m = p.matcher(cmd);
			// 校验用户名密码
			if (m.find())
			{
				String pwd = m.group(1);
				RealsocksUserDao realsocksUserDao = new RealsocksUserDaoImpl();
				RealsocksUser realsocksUser = realsocksUserDao.findByUserName(user.getUserName());
				if (realsocksUser != null && pwd.equals(realsocksUser.getRealUserPwd()))
				{
					logger.info("用户名[" + user.getUserName() + "]密码验证成功 登陆成功.......");
					user.setUserPwd(pwd);
					user.setLogin(true);
					return String.valueOf(ResponseCodeEnum.CMDEXECUTESUC.getCode());
				}
				else
				{
					logger.info("用户名[" + user.getUserName() + "]密码验证失败 需要密码.....");
					return String.valueOf(ResponseCodeEnum.ASKPWD.getCode());
				}
			}
		}
		logger.info("用户[" + user.getUserName() + "]已经登陆 无需再次登陆.......");
		return String.valueOf(ResponseCodeEnum.ERRORCMDSEQ.getCode());
	}

	/**
	 * @see com.ailk.bigdata.etl.realstream.server.service.UserCtlCmdService#addUserPermission(java.lang.String,
	 *      com.ailk.bigdata.etl.realstream.server.model.RealStreamUser)
	 */
	public String addUserPermission(String cmd, RealStreamUser user)
	{
		try
		{
			if (user.isLogin())
			{
				Pattern p = Pattern.compile(CmdEnum.ADD.getPattern());
				Matcher m = p.matcher(cmd);
				if (m.find())
				{
					logger.info("in meth 1");
					String onlyUnitCode = m.group(1);
					if (onlyUnitCode.equalsIgnoreCase("ALL"))
					{
						logger.info("in meth 1");
						user.setSupportAllCalc(true);
						logger.info("用户[" + user.getUserName() + "]添加所有单元编码成功.......");
						return String.valueOf(ResponseCodeEnum.CMDEXECUTESUC.getCode());
					}
					else
					{
						long code = Long.valueOf(onlyUnitCode);
						RealStreamUnitDao realStreamUnitDao = new RealStreamUnitDaoPGImpl();
						List<RealStreamUnit> unitList = realStreamUnitDao.getAllCalcUnitCode();
						if (CollectionUtils.isNotEmpty(unitList))
						{
							for (RealStreamUnit unit : unitList)
							{
								if (unit.getOnlyUnitCode() == code)
								{
									user.getCalcUnitCode().add(code);
									logger.info("用户[" + user.getUserName() + "]添加单元编码[" + code + "]成功.......");
									return String.valueOf(ResponseCodeEnum.CMDEXECUTESUC.getCode());
								}
							}
						}
						return String.valueOf(ResponseCodeEnum.INVALIDCMDPARAM.getCode());
					}
				}
			}
			logger.info("用户[" + user.getUserName() + "]未登陆 无法添加单元编码.......");
			return String.valueOf(ResponseCodeEnum.USERUNLOGIN.getCode());
		}
		catch (Exception e)
		{
			logger.error("用户[" + user.getUserName() + "]添加计算规则失败", e);
			return String.valueOf(ResponseCodeEnum.INVALIDCMDPARAM.getCode());
		}
	}

	/**
	 * @see com.ailk.bigdata.etl.realstream.server.service.UserCtlCmdService#rmUserPermission(java.lang.String,
	 *      com.ailk.bigdata.etl.realstream.server.model.RealStreamUser)
	 */
	public String rmUserPermission(String cmd, RealStreamUser user)
	{
		try
		{
			if (user.isLogin())
			{
				Pattern p = Pattern.compile(CmdEnum.ADD.getPattern());
				Matcher m = p.matcher(cmd);
				if (m.find())
				{
					String onlyUnitCode = m.group(1);
					if (onlyUnitCode.equalsIgnoreCase("ALL"))
					{
						user.getCalcUnitCode().clear();
						user.setSupportAllCalc(false);
						logger.info("用户[" + user.getUserName() + "]移除所有单元编码成功.......");
						return String.valueOf(ResponseCodeEnum.CMDEXECUTESUC.getCode());
					}
					else
					{
						long code = Long.valueOf(onlyUnitCode);
						RealStreamUnitDao realStreamUnitDao = new RealStreamUnitDaoPGImpl();
						List<RealStreamUnit> unitList = realStreamUnitDao.getAllCalcUnitCode();
						if (user.isSupportAllCalc())
						{
							user.getCalcUnitCode().clear();
							for (RealStreamUnit unit : unitList)
							{
								user.getCalcUnitCode().add(unit.getOnlyUnitCode());
							}
						}
						if (CollectionUtils.isNotEmpty(unitList))
						{
							for (RealStreamUnit unit : unitList)
							{
								if (unit.getOnlyUnitCode() == code && user.getCalcUnitCode().remove(code))
								{
									logger.info("用户[" + user.getUserName() + "]移除单元编码[" + code + "]成功.......");
									return String.valueOf(ResponseCodeEnum.CMDEXECUTESUC.getCode());
								}
							}
						}
						return String.valueOf(ResponseCodeEnum.INVALIDCMDPARAM.getCode());
					}
				}
			}
			logger.info("用户[" + user.getUserName() + "]未登陆 无法添加单元编码.......");
			return String.valueOf(ResponseCodeEnum.USERUNLOGIN.getCode());
		}
		catch (Exception e)
		{
			logger.error("用户[" + user.getUserName() + "]添加计算规则失败", e);
			return String.valueOf(ResponseCodeEnum.INVALIDCMDPARAM.getCode());
		}
	}

	/**
	 * @see com.ailk.bigdata.etl.realstream.server.service.UserCtlCmdService#connect(java.lang.String,
	 *      com.ailk.bigdata.etl.realstream.server.model.RealStreamUser)
	 */
	public String connect(String cmd, RealStreamUser user)
	{
		if (!user.isLogin())
		{
			logger.info("用户未登陆 无法打开数据连接.......");
			return String.valueOf(ResponseCodeEnum.USERUNLOGIN.getCode());
		}
		// else if (!user.isOpenDataConn())
		// {
		// logger.info("用户[" + user.getUserName() + "]无法打开数据连接");
		// return String.valueOf(ResponseCodeEnum.UNOPENDATACONN.getCode());
		// }
		else
		{
			logger.info("用户[" + user.getUserName() + "]数据连接已经打开 开始传输");
			Pattern p = Pattern.compile(CmdEnum.CONNECT.getPattern());
			Matcher m = p.matcher(cmd);
			if (m.find())
			{
				String dataConnPort = m.group(1);
				user.setDataConnPort(Integer.parseInt(dataConnPort));
				user.setOpenDataConn(true);
				RealStreamTool.AUTHORISED_USER_INFO.put(user.getClientIP() + ":" + dataConnPort, user);
				// return
				// String.valueOf(ResponseCodeEnum.DATACONNISTRANS.getCode());
				return String.valueOf(ResponseCodeEnum.CMDEXECUTESUC.getCode());
			}
		}
		return String.valueOf(ResponseCodeEnum.UNOPENDATACONN.getCode());
	}

	/**
	 * @see com.ailk.bigdata.etl.realstream.server.service.UserCtlCmdService#disConnect(java.lang.String,
	 *      com.ailk.bigdata.etl.realstream.server.model.RealStreamUser)
	 */
	public String disConnect(String cmd, RealStreamUser user)
	{
		if (user.isOpenDataConn())
		{
			RealStreamTool.AUTHORISED_USER_INFO.remove(user.getClientIP() + ":" + user.getDataConnPort());
			logger.info("用户[" + user.getUserName() + "]无法打开数据连接");
			// return String.valueOf(ResponseCodeEnum.DATACONNCLOSE.getCode());
			return String.valueOf(ResponseCodeEnum.CMDEXECUTESUC.getCode());
		}
		logger.info("用户[" + user.getUserName() + "]数据端口没有打开 不需要进行关闭.......");
		return String.valueOf(ResponseCodeEnum.ERRORCMDSEQ.getCode());
	}

	/**
	 * @see com.ailk.bigdata.etl.realstream.server.service.UserCtlCmdService#exit(java.lang.String,
	 *      com.ailk.bigdata.etl.realstream.server.model.RealStreamUser)
	 */
	public String exit(String cmd, RealStreamUser user)
	{
		if (user.isLogin() && user.isOpenDataConn())
		{
			RealStreamTool.AUTHORISED_USER_INFO.remove(user.getClientIP() + ":" + user.getDataConnPort());
		}
		logger.info(user.getClientIP());
		return String.valueOf(ResponseCodeEnum.CMDEXECUTESUC.getCode());
	}

	/**
	 * @see com.ailk.bigdata.etl.realstream.server.service.UserCtlCmdService#viewUserPermission(java.lang.String,
	 *      com.ailk.bigdata.etl.realstream.server.model.RealStreamUser)
	 */
	public String viewUserPermission(String cmd, RealStreamUser user)
	{
		try
		{
			if (user.isLogin())
			{
				Pattern p = Pattern.compile(CmdEnum.ADD.getPattern());
				Matcher m = p.matcher(cmd);
				if (m.find())
				{
					String onlyUnitCode = m.group(1);
					if (onlyUnitCode.equalsIgnoreCase("ALL"))
					{
						// RealStreamUnitDao realStreamUnitDao = new
						// RealStreamUnitDaoPGImpl();
						// List<RealStreamUnit> unitList =
						// realStreamUnitDao.getAllCalcUnitCode();
					}
					else
					{
						RealStreamUnitDao realStreamUnitDao = new RealStreamUnitDaoPGImpl();
						List<RealStreamUnit> unitList = realStreamUnitDao.getAllCalcUnitCode();
						if (user.isSupportAllCalc())
						{
							user.getCalcUnitCode().clear();
							for (RealStreamUnit unit : unitList)
							{
								user.getCalcUnitCode().add(unit.getOnlyUnitCode());
							}
						}
					}
				}
			}
			logger.info("用户[" + user.getUserName() + "]未登陆 无法添加单元编码.......");
			return String.valueOf(ResponseCodeEnum.USERUNLOGIN.getCode());
		}
		catch (Exception e)
		{
			logger.error("用户[" + user.getUserName() + "]添加计算规则失败", e);
			return String.valueOf(ResponseCodeEnum.INVALIDCMDPARAM.getCode());
		}
	}

}
